import numpy as np
from PIL import Image, ImageFilter
import matplotlib.pyplot as plt

# 读取图像并转为灰度图
img = Image.open('dog.jpg').convert('L')

# 创建一个与图像大小相同的随机噪声矩阵，噪声值符合20倍标准正太分布
noise = np.random.normal(0, 20, img.size).reshape(img.size[0], img.size[1])

# 将噪声矩阵添加到原始的灰度图像上
noisy_img = Image.fromarray((np.array(img) + noise.T).astype(np.uint8))

# 显示两张子图
fig, axs = plt.subplots(1, 2, figsize=(10, 5))
axs[0].imshow(img, cmap='gray')
axs[0].set_title('Original')
axs[1].imshow(noisy_img, cmap='gray')
axs[1].set_title('Noisy')
for ax in axs:
    ax.set_axis_off()
plt.show()


from PIL import Image
import numpy as np
from tabulate import tabulate

# 读取图片并转换为numpy数组
img = Image.open("dog.jpg")
img_array = np.array(img)

# 提取三个通道的数据
r, g, b = img_array[:, :, 0], img_array[:, :, 1], img_array[:, :, 2]

# 计算每个通道的最大值、最小值、平均值、标准差以及分位数
max_r, max_g, max_b = np.max(r), np.max(g), np.max(b)
min_r, min_g, min_b = np.min(r), np.min(g), np.min(b)
mean_r, mean_g, mean_b = np.mean(r), np.mean(g), np.mean(b)
std_r, std_g, std_b = np.std(r), np.std(g), np.std(b)
percentile_25_r, percentile_25_g, percentile_25_b = np.percentile(r, 25), np.percentile(g, 25), np.percentile(b, 25)
percentile_50_r, percentile_50_g, percentile_50_b = np.percentile(r, 50), np.percentile(g, 50), np.percentile(b, 50)
percentile_75_r, percentile_75_g, percentile_75_b = np.percentile(r, 75), np.percentile(g, 75), np.percentile(b, 75)

# 使用tabulate库将结果以表格的形式展示出来
table = [["max", max_r, max_g, max_b],
         ["min", min_r, min_g, min_b],
         ["mean", mean_r, mean_g, mean_b],
         ["std", std_r, std_g, std_b],
         ["25%", percentile_25_r, percentile_25_g, percentile_25_b],
         ["50%", percentile_50_r, percentile_50_g, percentile_50_b],
         ["75%", percentile_75_r, percentile_75_g, percentile_75_b]]

print(tabulate(table, headers=["meta", "R", "G", "B"]))

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

# 读取图片并转换为numpy数组
img = Image.open("dog.jpg")
img_array = np.array(img)

# 创建一个与图像大小相同的随机噪声矩阵，噪声值符合20倍标准正太分布
noise = np.random.normal(0, 20, img_array.shape).astype(np.uint8)

# 将噪声矩阵添加到原始的RGB图像上
noisy_img_array = (img_array + noise).clip(0, 255)

# 将numpy数组转换回PIL图像
noisy_img = Image.fromarray(noisy_img_array)

# 使用matplotlib库将两张子图并列显示出来
fig, axs = plt.subplots(1, 2, figsize=(10, 5))
axs[0].imshow(img)
axs[0].set_title('Original')
axs[1].imshow(noisy_img)
axs[1].set_title('Noisy')
for ax in axs:
    ax.set_axis_off()
plt.show()


from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

# 读取图片并转换为numpy数组
img = Image.open("dog.jpg")
img_array = np.array(img)

# 创建一个与图像大小相同的随机噪声矩阵，噪声值符合20倍标准正太分布
noise = np.random.normal(0, 20, img_array.shape).astype(np.uint8)

# 将噪声矩阵添加到原始的RGB图像上
noisy_img_array = (img_array + noise).clip(0, 255)

# 将numpy数组转换回PIL图像
noisy_img = Image.fromarray(noisy_img_array)

# 使用matplotlib库将三行子图显示出来
fig, axs = plt.subplots(3, 2, figsize=(10, 15))
axs[0, 0].imshow(img)
axs[0, 0].set_title('Original')
axs[0, 1].imshow(noisy_img)
axs[0, 1].set_title('Noisy')
axs[1, 0].imshow(img_array[:, :, 0], cmap='Reds')
axs[1, 0].set_title('R Channel')
axs[1, 1].imshow(img_array[:, :, 1], cmap='Greens')
axs[1, 1].set_title('G Channel')
axs[2, 0].imshow(img_array[:, :, 2], cmap='Blues')
axs[2, 0].set_title('B Channel')
axs[2, 1].imshow(img_array.mean(axis=2), cmap='gray')
axs[2, 1].set_title('Grayscale')
for ax in axs.flat:
    ax.set_axis_off()
plt.tight_layout()
plt.show()


import cv2
import numpy as np

# 读取前景图和背景图
foreground = cv2.imread('monkey.jpg')  # 移除cv2.IMREAD_GRAYSCALE
background = cv2.imread('moon.jpg')  # 移除cv2.IMREAD_GRAYSCALE

bg_height, bg_width = background.shape[:2]

# 调整前景图像的尺寸以匹配背景图像的尺寸
foreground = cv2.resize(foreground, (bg_width, bg_height))
# 确保两张图片的大小相同
assert foreground.shape == background.shape, "The sizes of the two images must be the same."

# 使用numpy的比较运算来实现特效
result = np.where(foreground > background, foreground, background)

# 显示结果
cv2.imshow('Result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()


import cv2
import numpy as np

def skeletonize(img):
    # 将图像转换为灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 使用Otsu's二值化方法
    ret, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

    # 定义形态学操作的结构元素
    kernel = np.ones((3, 3), np.uint8)

    # 进行形态学操作
    while True:
        # 先进行膨胀操作
        dilated = cv2.dilate(binary, kernel, iterations=1)

        # 再进行腐蚀操作
        eroded = cv2.erode(binary, kernel, iterations=1)

        # 使用np.bitwise_not和np.bitwise_and模拟XOR
        xor_result = np.bitwise_and(np.bitwise_not(dilated), np.bitwise_not(eroded))

        # 更新原始二值图像
        binary = xor_result

        # 如果图像不再发生变化，则停止循环
        if not np.any(binary != xor_result):
            break

    return binary

# 读取图像并指定为灰度图
img = cv2.imread('plant.png')

# 提取骨架
skeleton = skeletonize(img)

# 显示结果
cv2.imshow('Skeleton', skeleton)
cv2.waitKey(0)
cv2.destroyAllWindows()
